/*
 *  Filename:      meos_protocol.c
 *  Author:         Erick Huang<erickhuang1989@gmail.com>
 *  Revised:        2014-12-23
 *  Description:   
 *
 *  Copyright (c) Erick Huang. All rights reserved.
 */
#include "meos_api.h"
#include "meos_protocol.h"

/* Task ID for internal task/event processing */
static uint8 Prot_TaskID;

// Registered Receive msg task ID, initialized to NOT USED.
static uint8 registerMsgTaskID = TASK_NO_TASK;
static ProtCBs_t *registerAppCallbacks = NULL;

static void Prot_ProcessMEOSMsg( meos_msg_data_hdr_t *pMsg );
static void Prot_ProcessMsgEvent( ProtEvent_t *pEvent );


void Prot_Init( uint8 task_id )
{
	Prot_TaskID = task_id;
}

uint16 Prot_ProcessEvent( uint8 task_id, uint16 events )
{
	VOID task_id;

	if ( events & SYS_EVENT_MSG )
  	{
    	uint8 *pMsg;

    	if ( (pMsg = meos_msg_receive( App_TaskID )) != NULL )
    	{
      		Prot_ProcessMEOSMsg( (meos_msg_data_hdr_t *)pMsg );

      		// Release the OSAL message
      		meos_msg_deallocate( pMsg );
    	}
    	return (events ^ SYS_EVENT_MSG);
  	}

	// Discard unknown events
	return 0;
}

static void Prot_ProcessMEOSMsg( meos_msg_data_hdr_t *pMsg )
{
  	switch ( pMsg->type )
  	{
    	case MSG_TYPE_PROTOCOL_MSG_EVENT:
      		Prot_ProcessMsgEvent( (ProtEvent_t *)pMsg );
      		break;
  	}
}

static void Prot_ProcessMsgEvent( ProtEvent_t *pEvent )
{
  	switch ( pEvent->prot.opcode)
  	{
    	case PROT_EVENT_INIT_DONE:
      		/* do something */
			pEvent->initDone.data = 100;  //for example
      		break;
  	}

	// Pass event to app
  	if ( registerAppCallbacks && registerAppCallbacks->eventCB )
  	{
    	registerAppCallbacks->eventCB( pEvent );
  	}
}

Status_t Prot_SetParameter( uint8 param, uint8 len, void *pValue )
{
	Status_t ret = SUCCESS;
  	switch ( param )
  	{
    	case PROT_PARAM_1:
   			/* copy param to here */
      		break;
		case PROT_PARAM_2:
   			/* copy param to here */
      		break;
		default:
			ret = FAILURE;
  	}
	return ret;
}

Status_t Prot_GetParameter( uint8 param, uint8 len, void *pValue )
{
	Status_t ret = SUCCESS;
  	switch ( param )
  	{
    	case PROT_PARAM_1:
   			/* copy param to buf */
      		break;
		case PROT_PARAM_2:
   			/* copy param to buf */
      		break;
		default:
			ret = FAILURE;
  	}
	return ret;
}

Status_t Prot_RegisterForMsg( uint8 taskId )
{
	// Allow only the first task
  	if ( registerMsgTaskID == TASK_NO_TASK )
  	{
    	registerMsgTaskID = taskId;
    	return SUCCESS;
  	}
  	else
    	return FAILURE;
}

Status_t Prot_RegisterAppCBs( ProtCBs_t *appCallbacks )
{
  	if ( registerAppCallbacks == NULL )
  	{
    	registerAppCallbacks = appCallbacks;
		return SUCCESS;
  	}
	else
    	return FAILURE;
}

Status_t Prot_Start( ProtCBs_t *appCallbacks )
{
  	if ( appCallbacks )
  	{
    	registerAppCallbacks = appCallbacks;
  	}

  	//do some init.

	return SUCCESS;
}

